package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.UserLocation;
import com.tanhua.domain.vo.UserLocationVo;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserLocationApiImpl implements UserLocationApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 上报地理位置
     *
     * @param pojo
     */
    @Override
    public void save(UserLocation pojo,Double latitude, Double longitude) {
        long timeMillis = System.currentTimeMillis();
        // 构建点坐标
        GeoJsonPoint point = new GeoJsonPoint(longitude,latitude);
        pojo.setLocation(point);
        //1. 通过用户id判断记录是否存在
        Query query = new Query(Criteria.where("userId").is(pojo.getUserId()).and("userId").ne(pojo.getUserId()));
        if (mongoTemplate.exists(query, UserLocation.class)) {
            //2. 存在则更新坐标
            Update update = new Update();
            update.set("location", pojo.getLocation());
            update.set("updated", timeMillis);
            update.set("address", pojo.getAddress());
            mongoTemplate.updateFirst(query,update, UserLocation.class);
        }else {
            pojo.setCreated(timeMillis);
            pojo.setUpdated(timeMillis);
            //3. 不存在则添加数据
            mongoTemplate.insert(pojo);
        }
    }

    /**
     * 搜附近
     *
     * @param userId
     * @param distance  单位是 米
     * @return
     */
    @Override
    public List<UserLocationVo> searchNearBy(Long userId, Long distance) {
        List<UserLocationVo> list = new ArrayList<>();
        //1.查询登录用户的坐标
        Query query = new Query(Criteria.where("userId").is(userId));
        UserLocation loginUserLocation = mongoTemplate.findOne(query, UserLocation.class);
        if(null != loginUserLocation) {
            // 创建半径 p1:长度，P2：单位
            Distance radius = new Distance(distance/1000, Metrics.KILOMETERS);
            //2.以登录用户坐标为圆心，构建圆(p1:坐标点，p2:半径)
            Circle circle = new Circle(loginUserLocation.getLocation(), radius);
            //3.查询
            // 参数是Circle圆
            Query nearByQuery = new Query(Criteria.where("location").withinSphere(circle));
            List<UserLocation> userLocations = mongoTemplate.find(nearByQuery, UserLocation.class);
            //把数据转成UserLocationVo(原因：GeoJsonPoint反序列化时失败，把经纬取来单独存储)
            list = UserLocationVo.formatToList(userLocations);
        }
        // 刚注册，还没有坐标记录，5分钟或位移大于500M时才会有记录
        return list;
    }
}
